import { useState, forwardRef, useImperativeHandle } from "react";
import { Direction } from "./../../context";
import {
  useEventBind,
  useSnakeBodyGenerate,
  useSnakeHeadMove,
  useSnakeBodyMove,
  useResetSnake,
} from "./hook";
import config from "../../config";
import "./index.css";

/** 创建蛇节点 */
function createSnakeNode(
  index: number,
  x: number,
  y: number,
  size: number,
  direction: string
): SnakeNode {
  return {
    x,
    y,
    index,
    direction,
    width: size,
    height: size,
  };
}

/** 创建蛇头 */
function createSnakeHead(): SnakeNode {
  return createSnakeNode(
    0,
    config.snakePoint.x,
    config.snakePoint.y,
    config.gridSize,
    config.direction
  );
}

export default forwardRef(function Snake(_, ref) {
  const [direction, setDirection] = useState(config.direction as Direction);
  const [snakeHead, setSnakeHead] = useState<SnakeNode>(createSnakeHead);
  const [snakeBody, setSnakeBody] = useState<SnakeNode[]>([snakeHead]);

  // 蛇身生成
  useSnakeBodyGenerate(
    direction,
    snakeHead,
    snakeBody,
    setSnakeBody,
    createSnakeNode
  );

  // 蛇头移动
  useSnakeHeadMove(direction, setSnakeHead);

  // 蛇身移动
  useSnakeBodyMove(direction, snakeHead, snakeBody, setSnakeBody);

  // 重置蛇
  useResetSnake(setSnakeHead, setSnakeBody, createSnakeHead);

  // 事件绑定
  useEventBind(direction, setDirection);

  // 暴露接口
  useImperativeHandle(
    ref,
    () => ({
      // 获取蛇头坐标
      getSnakeHeadPoint: () => ({
        x: snakeHead.x,
        y: snakeHead.y,
      }),
    }),
    [snakeHead.x, snakeHead.y]
  );

  return (
    <div className="snake">
      {snakeBody.map((item, index) => (
        <div
          className="snake-item"
          key={index}
          style={{
            width: item.width,
            height: item.height,
            left: item.x,
            top: item.y,
          }}
        ></div>
      ))}
    </div>
  );
});
